package com.projetosi.web.server.sistema.dao;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.projetosi.web.server.sistema.interfaces.IGenericDAO;
import com.projetosi.web.server.sistema.interfaces.IGenericObject;
import com.projetosi.web.server.sistema.objetos.Item;
import com.projetosi.web.server.sistema.persistencia.LerEscreveArquivo;
import com.projetosi.web.server.sistema.sistema.RepositorioDeDados;

/**
 * 
 * @author Felipe Jose, Filipe Alencar, Rodrigo de Brito, Thiago Goncalves, Victor Hugo Arcelino;
 *
 */
public class ItemDAO implements IGenericDAO{

	private static RepositorioDeDados _repositorio = RepositorioDeDados.getInstance();
	File arquivo = new File("itens.xml");

	
	/**
	 * Cadastra um novo item no sistema.
	 * @throws Exception 
	 */
	@Override
	public void cadastrar(IGenericObject objeto) throws Exception  {
		if(objeto instanceof Item){
			Item item = (Item) objeto;
			if(!LerEscreveArquivo.existeXml(arquivo)){
				_repositorio.getItens().add(item);
                _repositorio.atualizarDados(arquivo);
			}else{
				List<Item> itens = _repositorio.carregarDados(arquivo);
				itens.add(item);
				_repositorio.atualizarDados(arquivo);
			}
			
		}

	}

	/**
	 * Atualiza um item que foi alterado no repositorio de dados.
	 * @throws Exception 
	 */
	@Override
	public void alterar(IGenericObject objeto) throws Exception  {
		List<Item> itensCadastrados = null;
		if(objeto instanceof Item){
			Item itemAlterado = (Item) objeto;
			if(!LerEscreveArquivo.existeXml(arquivo)){
				itensCadastrados = _repositorio.getItens();
			}else{
				itensCadastrados = _repositorio.carregarDados(arquivo);
			}
			for (int i = 0; i < itensCadastrados.size(); i++) {
				if(itensCadastrados.get(i).equals(itemAlterado)){
					itensCadastrados.set(i, itemAlterado);
					_repositorio.setItens(itensCadastrados);
					_repositorio.atualizarDados(arquivo);
				}
			}
		}

	}

	/**
	 * Deleta um item do sistema.
	 */
	@Override
	public void deletar(IGenericObject objeto) throws Exception {
		List<Item> itensCadastrados = null;
		if(objeto instanceof Item){
			Item itemADeletar = (Item) objeto;
			if(!LerEscreveArquivo.existeXml(arquivo)){
				itensCadastrados = _repositorio.getItens();
			}else{
				itensCadastrados = _repositorio.carregarDados(arquivo);
			}
			for(Iterator<Item> it= itensCadastrados.iterator(); it.hasNext();){
				Item item = it.next();
				if(item.equals(itemADeletar)){
					it.remove();
					_repositorio.setItens(itensCadastrados);
					_repositorio.atualizarDados(arquivo);
					return;
				}
			}
	
		}	
	}

	/**
	 * Pesquisa um certo item cadastrado no sistema,a partir de uma certa chave.
	 *  @return Lista contendo os itens pesquisados
	 */
	@Override
	public List<IGenericObject> pesquisar(String filtro, String chave)throws Exception {
		if(filtro == null || chave == null){
			throw new Exception("Especifique o filtro e a chave da pesquisa.");
		}
		if(filtro.trim().isEmpty() || chave.trim().isEmpty()){
			throw new Exception("Voce deve deve definir o filtro e a chave da pesquisa.");
		}
		if(filtro.equals("id")){
			return pesquisarPorId(Integer.parseInt(chave));
		}
		if(filtro.equals("descricao")){
			return pesquisarPorDescricao((chave));
		}
		if(filtro.equals("nome")){
			return pesquisarPorNomeIncompleto(chave);
		}else if(filtro.equals("nomeCompleto")){
			return pesquisarPorNomeCompleto(chave);
		}if(filtro.equals("categoria")){
			return pesquisarPorCategoria((chave));
		}
		return pesquisarTodos();
	}
	
	/**
	 * Pesquisa um item a partir de alguma parte de seu nome.
	 *  @return Lista contendo os itens que possuem o nome usado como chave da pesquisa.
	 * @throws Exception 
	 */
	private List<IGenericObject> pesquisarPorNomeIncompleto(String nome) throws Exception{
		List<IGenericObject> itemsCadastrados = pesquisarTodos();
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		for (IGenericObject item : itemsCadastrados) {
			if(((Item)item).getNome().toLowerCase().contains((nome.toLowerCase()))){
				resultado.add(item);
			}
		}
		return resultado;
	}   
	
	/**
	 * Pesquisa um item a partir do seu nome completo.
	 *  @return Lista contendo o item pesquisado
	 * @throws Exception 
	 */
	private List<IGenericObject> pesquisarPorNomeCompleto(String nome) throws Exception{
		List<IGenericObject> itemsCadastrados = pesquisarTodos();
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		for (IGenericObject item : itemsCadastrados) {
			if(((Item)item).getNome().toLowerCase().equals((nome.toLowerCase()))){
				resultado.add(item);
			}
		}
		return resultado;
	}       
	
	/**
	 * Pesquisa um item a partir de sua descricao.
	 *  @return Lista contendo o item pesquisado
	 * @throws Exception 
	 */
	private List<IGenericObject> pesquisarPorDescricao(String descricao) throws Exception{
		List<IGenericObject> itemsCadastrados = pesquisarTodos();
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		for (IGenericObject item : itemsCadastrados) {
			if(((Item)item).getDescricao().toLowerCase().contains(descricao.toLowerCase())){
				resultado.add(item);
			}
		}
		return resultado;
	}
	private List<IGenericObject> pesquisarPorCategoria(String categoria) throws Exception{
		List<IGenericObject> itemsCadastrados = pesquisarTodos();
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		for (IGenericObject item : itemsCadastrados) {
			if(((Item)item).getNameCategoriaFromCategoria(((Item)item).getTipoDeItem()).toLowerCase().contains(categoria.toLowerCase()) ||
				((Item)item).getCategoriasSecundarias().contains(categoria))
				resultado.add(item);
		}
		return resultado;
	}

	/**
	 * Pesquisa um item a partir do seu id.
	 * @return Lista contendo o item pesquisado
	 * @throws Exception 
	 */
	private List<IGenericObject> pesquisarPorId(int id) throws Exception{
		List<IGenericObject> itemsCadastrados = pesquisarTodos();
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		for (IGenericObject item : itemsCadastrados) {
			if(((Item)item).getId() == id){
				resultado.add(item);
			}
		}
		return resultado;
	}

	/**
	 * Pesquisa todos os itens cadastrados no sistema
	 * @return Lista de todos os itens cadastrados no sistema
	 * @throws Exception 
	 */
	@Override
	public List<IGenericObject> pesquisarTodos() throws Exception {
		List<Item> itensCadastrados = null;
		List<IGenericObject> resultado = new ArrayList<IGenericObject>();
		if(!LerEscreveArquivo.existeXml(arquivo)){
			itensCadastrados = _repositorio.getItens();
		}else{
			itensCadastrados = _repositorio.carregarDados(arquivo);
		}
		for (Item item : itensCadastrados) {
			if(item instanceof Item){
				resultado.add(item);
			}
		}
		return resultado;
	}
}


